#ifndef __UDSF_SPI_C__
#define __UDSF_SPI_C__

#include "app.h"

/*
*   notice:
*   UDSF 同UDF编程：不可调用cstd-lib,只可调用"sdk_ifs_udk_cfg.h"、"sys_api.h"中列出的API函数。
*   UDSF文件内函数均需使用static修饰符，且UDF中以#include "udsf_xxx.c"形式引用
*/

/*send data and 0xff->0xfd 0x02 0xfe->0xfd 0x01 0xfd->0xfd 0x00 */
static void udsf_usci0_spi_send_data_trans_without_cs(uint8_t*pData,int data_len){
	uint8_t data;
	
	for( int i=0;i<data_len;i++ ){
		if( pData[i] > 0xfc ){
			USCI0->TRX = 0xfd;
			data = pData[i] - 0xfd;
			while((Read_M32(0x40000014)&USCI_ISR_TXE_Msk)==0);
			USCI0->TRX = data;
		}
		else{
			USCI0->TRX = pData[i];
		}
		while((Read_M32(0x40000014)&USCI_ISR_TXE_Msk)==0);
	}
}

static void udsf_usci0_spi_send_data_base16_without_cs(uint8_t* pData,int data_len){

	uint8_t tmp_dataA,tmp_dataB,tmp_out;

	for( int i=0;i<data_len;i++ ){
		tmp_dataA = (pData[i]&0xf0)>>4;
		if( tmp_dataA > 9 ){
			tmp_out = 'A'+(tmp_dataA-10);
		}else{
			tmp_out = '0'+tmp_dataA;
		}
		USCI0->TRX = tmp_out;  // send high-4-bit
		
		tmp_dataB = (pData[i]&0x0f);
		if( tmp_dataB > 9 ){
			tmp_out = 'A'+(tmp_dataB-10);
		}else{
			tmp_out = '0'+tmp_dataB;
		}
		while((Read_M32(0x40000014)&USCI_ISR_TXE_Msk)==0);
		USCI0->TRX = tmp_out;  // send low-4-bit
		while((Read_M32(0x40000014)&USCI_ISR_TXE_Msk)==0);
		USCI0->TRX = ' ';      // send space
		while((Read_M32(0x40000014)&USCI_ISR_TXE_Msk)==0);
	}
}

/*usci0 spi*/
static void udsf_usci0_spi_deinit_without_cs(void){
	PINMUX->MUX0 = ((PINMUX->MUX0&0xffff000f)|0x0000);
}

// 仅支持 mode0 mode3
static void udsf_usci0_spi_init_without_cs(uint8_t cs_pin,uint8_t clk_div,uint8_t is_msb,uint8_t mode){
	
	PINMUX->MUX0 = ((PINMUX->MUX0&0xffff000f)|0x1110);
	
	SYSC->CLK_EN|=USCI0_EN_Msk;

	SYSC->SWRST &=~USCI0_SWRST_N_Msk;
	SYSC->SWRST |= USCI0_SWRST_N_Msk;
	
	// 默认mode0
	uint8_t pol = 0; // 低
	uint8_t sample_edge = 1;    // 上升沿
	
	if( mode == 1 ){
		pol = 0;            // 高
		sample_edge = 0;    // 下降沿
	}else if( mode == 2 ){
			pol = 1;          // 高
			sample_edge = 0;  // 下降沿
	}else if( mode == 3 ){
		pol = 1;            // 高
		sample_edge = 1;    // 上升沿
	}
	
	USCI0->CFG0 = 0;        // wk_mode=spi
	USCI0->CFG1 =   cs_pin<<20 | // slv cs gpio
									0<<19 | // slv cs lvl
									0<<18 | // master
									(pol<<17) | 
									(sample_edge<<16) | 
									0<<12 | // no inv
									0<<10 | // stop bit
									0<< 9 | // par_off
									0<< 8 | // par_typ
									(!is_msb<< 6) | // msb
									1<< 4 | // 8-bit
									0<< 2 | // no half-duplex
									1<< 1 | // rx_en
									1<< 0 ; // tx_en
		USCI0->BAUD = clk_div;//0:2分频  15:32分频
		USCI0->MOD  = 0;
		USCI0->CLK_DIV = 0; 
}

static void udsf_usci0_spi_rw_without_cs(uint8_t* p_cmd,int cmd_len,uint8_t *data,int data_len){

	for( int i=0;i<cmd_len;i++ ){
		USCI0->TRX = p_cmd[i];
		while((USCI0->ISR&USCI_ISR_TXE_Msk)==0);
	}
	for( int i=0;i<data_len;i++ ){
		USCI0->TRX = 0xff;
		while((USCI0->ISR&USCI_ISR_TXE_Msk)==0);
		data[i] = USCI0->TRX;
	}
	while ((USCI0->ISR & USCI_ISR_TE_Msk) == 0);
	//USCI0->ISR = USCI_ISR_TE_Msk;
}

inline static void udsf_usci0_spi_rw_without_cs_inline(uint8_t* p_cmd,int cmd_len,uint8_t *data,int data_len){

	for( int i=0;i<cmd_len;i++ ){
		USCI0->TRX = p_cmd[i];
		while((USCI0->ISR&USCI_ISR_TXE_Msk)==0);
	}
	for( int i=0;i<data_len;i++ ){
		USCI0->TRX = 0xff;
		while((USCI0->ISR&USCI_ISR_TXE_Msk)==0);
		data[i] = USCI0->TRX;
	}
	while ((USCI0->ISR & USCI_ISR_TE_Msk) == 0);
	//USCI0->ISR = USCI_ISR_TE_Msk;
}

#endif
